package com.tungse.study.lock;

import lombok.ToString;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.locks.LockSupport;

public class MyLock {

    //CAS
    AtomicBoolean flag = new AtomicBoolean(false);
    Thread owner = null;
    AtomicReference<Node> head = new AtomicReference<>(new Node());
    AtomicReference<Node> tail = new AtomicReference<>(head.get());
    List<Thread> waiters = null; //等待队列

    public void lock() {
        if (flag.compareAndSet(false, true)) {
            System.out.println(Thread.currentThread().getName() + "直接获取锁成功");
            owner = Thread.currentThread();
            return;
        }
        Node current = new Node();
        current.thread = Thread.currentThread(); //当前节点的线程
        while (true) {
            Node currentTail = tail.get(); //当前尾节点
            if (tail.compareAndSet(currentTail, current)) { //如果当前节点是尾节点
                System.out.println(Thread.currentThread().getName() + "加入到了链表尾部");
                current.pre = currentTail;
                currentTail.next = current;
                break;
            }
        }
        while (true) {
            //condition
            //head -> A -> B -> C -> D -> null
            //如果当前节点的前一个节点是头节点，说明当前节点是头节点的下一个节点
            if (current.pre == head.get() && flag.compareAndSet(false, true)) {
                owner = Thread.currentThread();
                head.set(current); //将头节点设置为当前节点

                //断开当前节点与前一个节点的连接
                current.pre.next = null;
                current.pre = null;
                System.out.println(Thread.currentThread().getName() + "被唤醒获取锁成功");
                return;
            }
            LockSupport.park(); //阻塞当前线程
        }
    }

    public void unlock() {
        if (Thread.currentThread() != this.owner) {
            throw new IllegalStateException("当前线程并没有锁， 不能进行解锁操作!");
        }
        //唤醒head node的下一个节点
        Node headNode = head.get();
        Node nextNode = headNode.next;
        flag.set(false);
        //
        if(nextNode != null) {
            //唤醒下一个节点
            System.out.println(Thread.currentThread().getName() + " 唤醒下一个节点" + nextNode.getThreadName());
            LockSupport.unpark(nextNode.thread);
        }

    }

    class Node {
        Node pre;   //前一个节点
        Node next;  //后一个节点
        Thread thread; //当前节点的线程

        @Override
        public String toString() {
            String str = "Node{thread=" + getThreadName();
            if(pre != null) {
                str += ", pre=" + pre.getThreadName();
            } else {
                str += ", pre=null";
            }
            if(next != null) {
                str += ", next=" + next.getThreadName();
            } else {
                str += ", next=null";
            }

            str += "}";
            return str;
        }

        public String getThreadName() {
            if(thread != null) {
                return thread.getName();
            } else {
                return "";
            }

        }
    }
}
